import markdown
from django.db import models
from django.urls import reverse
from django.utils.html import strip_tags
from django.utils.text import slugify
from markdown.extensions.toc import TocExtension

from users.models import User


# 有哪几个模型
# 用户 文章 分类 标签 评论

# 模型分别有哪些字段
# 用户: id 昵称 电子邮箱 密码
# 分类：id 名称
# 标签：id 名称
# 文章：id author 创建时间 修改时间 阅读次数 标题 文章内容 摘要 分类
# 评论：id user 文章 内容 创建时间


class CreateTimeModel(models.Model):
    created_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    class Meta:
        abstract = True  # 抽象我们模型，在同步数据库的时候，不会真正的生成一个实体表


class Category(models.Model):
    name = models.CharField(max_length=32, unique=True, verbose_name='名称')
    desc = models.TextField(blank=True, verbose_name='描述')

    class Meta:  # 元数据
        verbose_name = '类别'
        verbose_name_plural = verbose_name

    def __str__(self):  # 用于得到能够代表模型对象的描述
        return self.name


class Tag(models.Model):
    name = models.CharField(max_length=32, unique=True, verbose_name='名称')

    class Meta:
        verbose_name = '标签'
        verbose_name_plural = verbose_name

    def __str__(self):  # 用于得到能够代表模型对象的描述
        return self.name


# 在模型里面，尽量不要换行
class Article(CreateTimeModel):
    author = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='作者')
    title = models.CharField(max_length=32, verbose_name='标题')
    content = models.TextField(verbose_name='内容')
    excerpt = models.CharField(max_length=128, blank=True, verbose_name='摘要')
    views = models.PositiveIntegerField(default=0, verbose_name='浏览次数')
    modified_time = models.DateTimeField(auto_now=True, verbose_name='修改时间')
    category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name='类别')
    tags = models.ManyToManyField(Tag, verbose_name='标签', blank=True)

    class Meta:
        verbose_name = '文章'
        verbose_name_plural = verbose_name
        ordering = ['-created_time']

    def __str__(self):  # 用于得到能够代表模型对象的描述
        return self.title

    def save(self, *args, **kwargs):
        if not self.excerpt:
            md = self.md_content()
            self.excerpt = strip_tags(md)[:128]
        super(Article, self).save(*args, **kwargs)
        # super().save(*args, **kwargs)  # python2不支持

    def md_content(self):
        # markdown:  pip install markdown
        # pygments: pip install pygments  # 安装好之后会自动实现高亮class的添加
        # return markdown.markdown(
        #     self.content,
        #     extensions=[
        #         'markdown.extensions.extra',
        #         'markdown.extensions.codehilite',
        #         'markdown.extensions.toc'
        #     ]
        # )
        md = self.get_md()
        return md.convert(self.content)

    @staticmethod
    def get_md():
        return markdown.Markdown(
            extensions=[
                'markdown.extensions.extra',
                'markdown.extensions.codehilite',
                TocExtension(slugify=slugify)
            ]
        )
        # 这是一个套路，以后按这个来就可以了

    def md_toc(self):
        md = self.get_md()
        md.convert(self.content)
        return md.toc

    def get_absolute_url(self):
        return reverse('blog:detail', kwargs={'pk': self.pk})

    def increase_views(self):
        self.views += 1
        self.save(update_fields=['views'])


class Comment(CreateTimeModel):
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='用户')
    article = models.ForeignKey(Article, on_delete=models.CASCADE, verbose_name='文章')
    content = models.TextField(max_length=1024, verbose_name='评论内容')

    class Meta:
        verbose_name = '评论'
        verbose_name_plural = verbose_name

    def __str__(self):  # 用于得到能够代表模型对象的描述
        return self.content

# on_delete 说明
# https://docs.djangoproject.com/zh-hans/2.1/ref/models/fields/#django.db.models.ForeignKey
